# a grouping of reports into a single event or occurrence, allowing tracking and annotation
class Incident < ActiveRecord::Base
  has_many(:incident_reports, :dependent => :destroy)
  has_many(:reports, :through => :incident_reports)
  belongs_to(:category)

  before_save(:ensure_status)
  
  
  scope(:for_index, includes(:reports, :category))
  scope(:by_id, order("id DESC"))
  
  # 20 incidents max per page
  self.per_page = 20
  
  # builds an SQL fragment search condition based on the given query
  def self.search_condition(query)
    return "1" if query.blank?
    
    # break into tokens
    tokenlist = query.scan(/(\w+:?[^\s]+)/)
    
    # go through each token
    finalQueryTerms = []
    tokenlist.each do |str |
      # remove quotes because they are used for tokenizing, not content
      str = str [0].gsub("\"","")
      
      # if the token is now empty,skip it
      if str == ""
        next
      end
      
      # is this a qualifier?
      if str.match(/^(\w+):(.+)$/)
        qualifier, term = $1, $2
      else
        finalQueryTerms << "incidents.title LIKE '%" + str + "%'"
      end
    end
    
    # join the terms into an SQL string
    finalQueryTerms.join(" and ")
  end
  
  # string representation of incident ID for display in the interface
  def id_str
    '#' + id.to_s.rjust(3, '0')
  end
  
  # category full name or empty string if no category
  def category_name
    category ? category.full_name : ""
  end
  
  # adds a report to the incident
  def add_report(r)
    reports << r
    save
  end
  
  # returns the number of reports associated with the incident
  def num_rpts
    reports.count
  end
  
  protected
    # set default status
    def ensure_status
      self.status = "fresh" unless self.status
    end
end
